home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 130_01 / view.c < prev    next >
Text File  |  1985-03-09  |  9KB  |  399 lines

  1. /*
  2.     VIEW - Disk Block Viewer for CP/M v2
  3.  
  4.     written for BDS "C" v1.44 by
  5.  
  6.     Rick Hollinbeck
  7.     Box C
  8.     Norwood, CO  81423
  9.  
  10.     v1.0 - 10/19/81
  11. Note:
  12.     This program depends on:
  13.      1. v2.x CP/M
  14.      2. a modified 'bios' function which leaves HL untouched
  15.          for the seldsk function (9), but is otherwise compatible
  16.         with the standard library version.
  17.      3. A CRT with addressable cursor & clear screen capabilities.
  18.      4. A 'bdscio.h' with the strings CLEARS (clear screen) and
  19.          CURSADR (cursor addressing prefix to row, column) defined.
  20.      5. The direct bios disk i/o utilities (diskio.c & diskio.dcl)
  21. */
  22.  
  23. #include <a:bdscio.h>
  24. #include <diskio.dcl>
  25.  
  26. #define ALLXOFF 5    /* Home Row for Allocation Map */
  27. #define ALLYOFF 1    /* Home Column for Allocation Map */
  28. #define MXBITPOS 63    /* Last bit position to display per row */
  29. #define ALLYMAX (ALLYOFF + (MXBITPOS+1)/8 + MXBITPOS - 1)
  30.             /* Max column for alloc. map */
  31. #define MXBLOCK 0x4000    /* Maximum Block Size */
  32. #define MAXROW TLENGTH    /* CRT Maximum row */
  33. #define MAXCOL TWIDTH    /* CRT Maximum column */
  34.  
  35. /* CP/M 2.x Disk Parameter Tables */
  36.  
  37. struct dpb {    /* Disk Parameter Block */
  38.     unsigned spt;    /* Sectors/track */
  39.     char bsh;    /* block shift (3 = 1k, 4 = 2k, 5 = 4k, etc.) */
  40.     char blm;    /* a bit mask 'bsh' bits wide */
  41.     char exm;    /* extent mask (depends on dsm, 0 for 1k allocation) */
  42.     unsigned dsm;    /* maximum block number for drive */
  43.     unsigned drm;    /* maximum directory entry index */
  44.     char al[2];    /* Directory Allocation Bitmap */
  45.     unsigned cks;    /* size of checksum vector */
  46.     unsigned off;    /* Number of reserved tracks */
  47.     } *dpbp;    /* from dphp->hdpbp */
  48.  
  49. struct dph {    /* Disk Parameter Header */
  50.     char *xltp;    /* pointer to sector translation table */
  51.     int dscr[3];    /* BDOS scratch */
  52.     char *dirbp;    /* Pointer to directory buffer */
  53.     struct dpb *hdpbp; /* Disk Parameter Block pointer */
  54.     char *csvp;    /* Pointer to checksum vector */
  55.     char *alvp;    /* Pointer to Allocation Bitmap */
  56.     } *dphp;    /* returned by seldsk */
  57.  
  58. unsigned bls;        /* block size (bytes) */
  59. char curx, cury, bitpos, maxxpos, lstmxbit;
  60. char scurx, scury;
  61. char svcurx, svcury;
  62. char i, j, *dbufp, *bufp1, lineno;
  63. char *xltbp;
  64. unsigned usedblks, block, ii, jj, maxtrk, maxsec;
  65. struct dskadr dadr;
  66. char c, cdisk, abort;
  67. char ans[132];
  68. char dbuf[MXBLOCK];        /* Block Buffer */
  69.  
  70. main()
  71. {
  72. strt:
  73.     clearscrn();
  74.     cursor(MAXROW/2, 0);
  75.     printf("Disk Block Viewer");
  76.     printf(" v1.0\n");
  77.  
  78. getdsk:
  79.     printf("Enter Drive (A:, B:, etc.): ");
  80.     gets(ans);
  81.     bdos(14, c = (cdisk = toupper(ans[0])) - 'A');    /* Log in Drive */
  82.     if (!(dphp = bios(SELDSK, c))) {
  83.         printf("\n??? Select Error on %c:\n", cdisk);
  84.         goto getdsk;
  85.         }
  86.  
  87.     maxtrk = maxsec = (-1);    /* Disable diskio parameter checks */
  88.     bitpos = 0;
  89.     scurx = ALLXOFF;
  90.     scury = ALLYOFF;
  91. cloop:
  92.     abort = FALSE;
  93.     diskinfo();        /* Print Disk Characteristics */
  94.     printbm();        /* Print allocation map */
  95.  
  96.   /* Block select loop */
  97.  
  98.     cursor(curx + 2, 3);
  99.     printf("F - Fwd / B - Back / P - Up / N - Down / X - Examine");
  100.     printf(" / S - Select Disk");
  101.     printst();        /* Print sector translation table */
  102.     cursor(scurx, scury);
  103.     c = ' ';
  104.     while (c != ('C'-0x40)) {    /* ^C terminates */
  105.  
  106.         block = (curx - ALLXOFF) * (MXBITPOS + 1) + bitpos;
  107.         cursave();
  108.         cursor(MAXROW - 1, MAXCOL - 30);
  109.         printf("Block %u (dec) %x (hex) ", block, block);
  110.         curback();
  111.  
  112.         switch (c = toupper(getch())) {
  113.  
  114.         case ('F'-0x40): /* ^F */
  115.         case 'F':
  116.             if (block < dpbp->dsm)
  117.              if (bitpos < MXBITPOS) {
  118.                 if ((bitpos & 7) == 7) ++cury;
  119.                 cursor(curx, ++cury);
  120.                 ++bitpos;
  121.                 }
  122.              else { /* wrap to next line */
  123.                 cursor(++curx, ALLYOFF);
  124.                 bitpos = 0;
  125.                 }
  126.             break;
  127.  
  128.         case ('B'-0x40): /* ^B */
  129.         case 'B':
  130.             if (bitpos) {
  131.                 if (!(bitpos & 7)) --cury;
  132.                 cursor(curx, --cury);
  133.                 --bitpos;
  134.                 }
  135.             else { /* back up to previous line */
  136.                 if (curx > ALLXOFF) {
  137.                     cursor(--curx, ALLYMAX);
  138.                     bitpos = MXBITPOS;
  139.                 }}
  140.             break;
  141.  
  142.         case ('N'-0x40): /* ^N */
  143.         case 'N':
  144.             if (curx < maxxpos) {
  145.                 cursor(++curx, cury);
  146.                 }
  147.             break;
  148.  
  149.         case ('P'-0x40): /* ^P */
  150.         case 'P':
  151.             if (curx > ALLXOFF) {
  152.                 cursor(--curx, cury);
  153.                 }
  154.             break;
  155.             
  156.         case ('X'-0x40): /* ^X */
  157.         case 'X':
  158.             /* Get the block & Display it */
  159.             scurx = curx;
  160.             scury = cury;
  161.             cursor(MAXROW - 3, 0);
  162.             readblk(block);
  163.             for (dbufp = dbuf; dbufp < &dbuf[bls]; ++dbufp) {
  164.                 if ((c = *dbufp) == CPMEOF) break;
  165.                 if (c == '\r') continue;
  166.                 if (c == '\n') continue;
  167.                 if (c == '\t') continue;
  168.                 if (!printable(c)) {
  169.                     cursor(curx + 2, 0);
  170.                     printf("Looks binary, interested? ");
  171.                     if (!yes()) goto cloop;
  172.                     dmphex();
  173.                     goto cxdone;
  174.                     }
  175.                 }
  176.             cursor(curx + 2, 0);
  177.             printf("Looks like ASCII, Do you want hex display anyway? ");
  178.             if (yes()) dmphex();
  179.             else dmpascii();
  180.          cxdone:
  181.             if (!abort) {
  182.                 newline();
  183.                 pause();
  184.                 }
  185.             goto cloop;
  186.  
  187.          case ('S'-0x40):
  188.          case 'S':
  189.             goto strt;
  190.         }
  191.     }
  192.  
  193.     cursor (MAXROW - 2, 0);
  194.     exit();
  195.     }
  196.  
  197. diskinfo()
  198. {
  199.  
  200.   /* Print Disk Info */
  201.  
  202.     dpbp = dphp->hdpbp;
  203.     printf("%sDrive %c Characteristics:\n", CLEARS, cdisk);
  204.     printf("Sectors per Track: %u  ", dpbp->spt);
  205.     /* Calc block size */
  206.     printf("Block Size: %u  ",
  207.     bls = SECSIZ << dpbp->bsh);
  208.     printf("Max Block: %u  ", dpbp->dsm);
  209.     printf("Disk Size: %uk\n",
  210.         dpbp->dsm << (dpbp->bsh - 3));
  211.     printf("Reserved Tracks: %u", dpbp->off);
  212.     }
  213.  
  214. readblk(blk)
  215. unsigned blk;
  216. {
  217.     /* Determine the block's disk address */
  218.     dadr.track = (jj = (ii = bls/SECSIZ) * blk) / dpbp->spt + dpbp->off;
  219.     jj = jj % dpbp->spt;
  220.     dadr.sector = physec(jj);
  221.     clearscrn();
  222.     printf("Reading Track - Sector\n");
  223.     dbufp = dbuf;
  224.     while (ii--) {
  225.         cursor(++curx,10); printf("%u", dadr.track);
  226.         cursor(curx, 18); printf("%u", dadr.sector);
  227.         diskio(READ, &dadr, dbufp, 1, maxtrk, maxsec);
  228.         dbufp += SECSIZ;
  229.         if (++jj == dpbp->spt) {
  230.             jj = 0;
  231.             ++dadr.track;
  232.             }
  233.         dadr.sector = physec(jj);
  234.         }
  235.     }
  236.  
  237. unsigned physec(logsec)
  238. unsigned logsec;
  239. {
  240.     return dphp->xltp ? *(dphp->xltp + logsec) : (logsec + 1);
  241.     }
  242.  
  243. printbm()
  244. {
  245.     char abyt, bmsk, bit, *almapp;
  246.     unsigned bcnt;
  247.  
  248.     cursor(ALLXOFF - 2, (MAXCOL/2 - 12));
  249.     printf("Allocation Bit Map\n");
  250.     cursor(maxxpos = (ALLXOFF - 1), ALLYOFF);
  251.     printf("0      7 8     15 16    23 24    31 32    39 40    47");
  252.     printf(" 48    55 56    63");
  253.     almapp = dphp->alvp;    /* point to allocation map */
  254.     usedblks = 0;
  255.     for (bcnt = 0; bcnt <= dpbp->dsm; ++bcnt) {
  256.         if (bcnt & 7) { /* shift to next bit */
  257.             bit = ((abyt & (bmsk >>= 1)) != 0);
  258.             }
  259.         else { /* get next byte from vector */
  260.             bit = (((abyt = *almapp++) & (bmsk = 0x80)) != 0);
  261.             if (!(bcnt & 0x3f)) {
  262.                 ++maxxpos;
  263.                 lstmxbit = 0;
  264.                 cursor(++curx, ALLYOFF - 1);
  265.                 }
  266.             printf(" ");
  267.             }
  268.         ++lstmxbit;
  269.         printf("%u",bit);
  270.         usedblks += bit;
  271.         }
  272.     --lstmxbit;
  273.  
  274.     /* Print total allocated storage */
  275.     cursave();
  276.     cursor(ALLXOFF - 3, MAXCOL - 22);
  277.     printf("Blks Used: %u", usedblks);
  278.     curback();
  279.     }
  280.  
  281. printst()
  282. {
  283.     cursor(curx + 2, (MAXCOL/2 - 12));
  284.     printf("Sector Translation");
  285.     cursor(++curx, 0);
  286.     xltbp = dphp->xltp;
  287.     for (i = j = 0; i < dpbp->spt; ++i) {
  288.         if (j++ == (MAXCOL/8)) {
  289.             cursor(++curx, 0);
  290.             j = 1;
  291.             }
  292.         printf("%u:%u ", i+1, *xltbp++);
  293.         cursor(curx, cury + 8);
  294.         }
  295.     }
  296.  
  297. dmphex()
  298. {
  299.   clearscrn();
  300.   ii = 0;
  301.   for (dbufp = dbuf; dbufp < &dbuf[bls];) {
  302.     newline();
  303.     if (abort) return;
  304.     printf("%c%c%c0: ", hexd(ii>>8),
  305.                 hexd(ii>>4), hexd(ii));
  306.     ++ii;
  307.     bufp1 = dbufp;
  308.     for (j=0; j<16; ++j)
  309.     {
  310.      printf("%c%c ", hexd(*dbufp>>4),
  311.                      hexd(*dbufp));
  312.      ++dbufp;
  313.     }
  314.     printf(" |");
  315.     dbufp = bufp1;
  316.     for (j=0; j<16; ++j) {
  317.     putchar( printable(*dbufp) ? *dbufp : '_');
  318.     ++dbufp;
  319.     }
  320.     printf("|");
  321.    }
  322. }
  323.  
  324. dmpascii()
  325. {
  326.     clearscrn();
  327.     for (dbufp = dbuf; dbufp < &dbuf[bls]; ++dbufp) {
  328.         if ((c = *dbufp) == CPMEOF) break;
  329.         if (c == '\n') newline();
  330.         else putchar(c);
  331.         if (abort) return;
  332.         }
  333.     }
  334.  
  335. char hexd(dbyte)
  336. char dbyte;
  337. {
  338.   return
  339.     ( ((dbyte = dbyte & 0x0f) > 9